package com.xmtlxx.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.xmtlxx.common.core.domain.PageQuery;
import com.xmtlxx.common.core.page.TableDataInfo;
import com.xmtlxx.common.utils.StringUtils;
import com.xmtlxx.wms.domain.Cabinet;
import com.xmtlxx.wms.domain.CabinetGroup;
import com.xmtlxx.wms.domain.Locator;
import com.xmtlxx.wms.domain.bo.CabinetBo;
import com.xmtlxx.wms.domain.vo.CabinetVo;
import com.xmtlxx.wms.mapper.CabinetGroupMapper;
import com.xmtlxx.wms.mapper.CabinetMapper;
import com.xmtlxx.wms.mapper.LocatorMapper;
import com.xmtlxx.wms.mapper.StoreMapper;
import com.xmtlxx.wms.service.ICabinetService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 柜号Service业务层处理
 *
 * @author xmtlxx
 * @date 2022-12-15
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class CabinetServiceImpl implements ICabinetService {

    private final CabinetMapper baseMapper;

    private final StoreMapper storeMapper;

    private final CabinetGroupMapper cabinetGroupMapper;

    private final LocatorMapper locatorMapper;

    /**
     * 查询柜号
     *
     * @param id 柜号主键
     * @return 柜号
     */
    @Override
    public CabinetVo queryById(String id){
        //return baseMapper.selectVoById(id);
        return baseMapper.selectCabinetVoByID(id);
    }

    /**
     * 查询柜号列表
     *
     * @param bo 柜号
     * @return 柜号
     */
    @Override
    public TableDataInfo<CabinetVo> queryPageList(CabinetBo bo, PageQuery pageQuery) {
       // LambdaQueryWrapper<Cabinet> lqw = buildQueryWrapper(bo);
       // Page<CabinetVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        Page<CabinetVo> result = baseMapper.selectPageCabinetList(pageQuery.build(), bo);
        return TableDataInfo.build(result);
    }

    /**
     * 查询柜号列表
     *
     * @param bo 柜号
     * @return 柜号
     */
    @Override
    public List<CabinetVo> queryList(CabinetBo bo) {
       // LambdaQueryWrapper<Cabinet> lqw = buildQueryWrapper(bo);
       // return baseMapper.selectVoList(lqw);
        return baseMapper.selectCabinetList(bo);
    }

    private LambdaQueryWrapper<Cabinet> buildQueryWrapper(CabinetBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Cabinet> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getId()), Cabinet::getId, bo.getId());
        lqw.like(StringUtils.isNotBlank(bo.getName()), Cabinet::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getCno()), Cabinet::getCno, bo.getCno());
        lqw.eq(bo.getDeptId() != null, Cabinet::getDeptId, bo.getDeptId());
        lqw.eq(StringUtils.isNotBlank(bo.getStoreId()), Cabinet::getStoreId, bo.getStoreId());
        lqw.eq(StringUtils.isNotBlank(bo.getAreaId()), Cabinet::getAreaId, bo.getAreaId());
        lqw.eq(StringUtils.isNotBlank(bo.getGroupId()), Cabinet::getGroupId, bo.getGroupId());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), Cabinet::getType, bo.getType());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), Cabinet::getStatus, bo.getStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getDelFlag()), Cabinet::getDelFlag, bo.getDelFlag());
        return lqw;
    }

    /**
     * 新增柜号
     *
     * @param bo 柜号
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(CabinetBo bo) {
        Cabinet add = BeanUtil.toBean(bo, Cabinet.class);
        validEntityBeforeSave(add);
        CabinetGroup group = cabinetGroupMapper.selectById(bo.getGroupId());
        //填充UUID
        add.setId(IdUtil.simpleUUID());
        add.setDelFlag("0");
        add.setDeptId(group.getDeptId());
        add.setStoreId(group.getStoreId());
        add.setAreaId(group.getAreaId());

//        add.setDeptId(storeMapper.selectVoById(add.getStoreId()).getDeptId());

        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
            Long totals = baseMapper.selectCount(new LambdaQueryWrapper<Cabinet>().eq(Cabinet::getGroupId,bo.getGroupId()));
            group.setCnums(totals);
            cabinetGroupMapper.updateById(group);
        }
        return flag;
    }

    /**
     * 修改柜号
     *
     * @param bo 柜号
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(CabinetBo bo) {
        Cabinet update = BeanUtil.toBean(bo, Cabinet.class);
        validEntityBeforeSave(update);

        LambdaQueryWrapper<Locator> lqw = Wrappers.lambdaQuery();
        lqw.eq(Locator::getCabinetId,bo.getId());
        update.setLnums(locatorMapper.selectCount(lqw));

        boolean flag = baseMapper.updateById(update) > 0;
        if(flag && StringUtils.isNotBlank(bo.getGroupId())){
            Long totals = baseMapper.selectCount(new LambdaQueryWrapper<Cabinet>().eq(Cabinet::getGroupId,bo.getGroupId()));
            CabinetGroup group = new CabinetGroup();
            group.setId(bo.getGroupId());
            group.setCnums(totals);
            cabinetGroupMapper.updateById(group);
        }
        return flag;
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(Cabinet entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除柜号
     *
     * @param ids 需要删除的柜号主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        LambdaQueryWrapper<Locator> locatorCons = new LambdaQueryWrapper<Locator>();
        locatorCons.in(Locator::getCabinetId,ids);
        int flag = locatorMapper.delete(locatorCons);
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public Boolean insertBatchByVo(CabinetVo vo) {
        CabinetGroup cabinetGroup = cabinetGroupMapper.selectById(vo.getCabinetGroupId());
        Long cnums  = cabinetGroup.getCnums() == null ? 1 : cabinetGroup.getCnums() + 1;
        Long seq = vo.getSeq() != null ? vo.getSeq() : cnums;
        Integer adds = 0;
        for(int i = vo.getStartNo();i<=vo.getEndNo();i++){
            Cabinet add = new Cabinet();
            add.setId(IdUtil.simpleUUID());
            add.setDelFlag("0");
            add.setDeptId(cabinetGroup.getDeptId());
            add.setStoreId(cabinetGroup.getStoreId());
            add.setAreaId(cabinetGroup.getAreaId());
            add.setCno((StringUtils.isNotEmpty(vo.getCno())?vo.getCno()+i:cabinetGroup.getCno()+"排"+i+"架"));
            add.setName(add.getCno());
            add.setStatus("0");
            add.setPnums(0l);
            add.setLnums(0l);
            add.setSeq(seq);
            add.setType(cabinetGroup.getType());
            add.setFloors(vo.getFloors());
            add.setUseDeptId(cabinetGroup.getUseDeptId());
            add.setGroupId(cabinetGroup.getId());
            baseMapper.insert(add);
            seq++;
            adds++;
        }
        cabinetGroup.setCnums(cabinetGroup.getCnums()!= null? cabinetGroup.getCnums()+adds : adds );
        cabinetGroupMapper.updateById(cabinetGroup);
        return true;
    }
}
